home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / lib / rle_xwin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-07  |  14.3 KB  |  494 lines

  1. /*    RLE_X_WINDOW . C
  2. %
  3. %    Copyright (c)    Jin Guojun    1991
  4. %
  5. %    get_pic(img, window_geometry, previous_img, img_info)
  6. %    handle_exposure(img, x, y, width, height, img_h, sub_win)
  7. %    void    DumpScan_to_dpy(img)
  8. %    void    init_img_info(img, dpy)
  9. %    Maintain_Flush(img, previous, imgp, image_y)
  10. %    MapRGB(img, prev_img, imgp, data_buf, save_scan, max_h-y, w, y, icn_fact)
  11. %
  12. % AUTHOR:    Jin Guojun - LBL    8/1/91
  13. */
  14.  
  15. #include "panel.h"
  16. #include "imagedef.h"
  17.  
  18. #ifndef    VERS_COLOR_TUNER
  19. #define    VERS_COLOR_TUNER    "N18-1"
  20. #endif
  21. #ifndef    HELP_INFO
  22. #define    HELP_INFO    "CTRL+button => panel"
  23. #endif
  24. #ifdef    HIPS2_HF
  25. extern    char*    Progname;
  26. #define    progname Progname
  27. #else
  28. extern    char*    progname;
  29. #endif
  30.  
  31. bool    tuner_flag, OsameI,
  32.     multi_hd;    /* for multi_frame RLE */
  33.  
  34. void
  35. DumpScan_to_dpy(img)    /* dump entire image to the screen */
  36. image_information*    img;
  37. {
  38. byte    *read_scan[3], *save_scan[3];
  39. register int    i, y=img->h;
  40.     while (y--)    {
  41.         read_scan[0] = ORIG_RLE_ROW(img, y-1);
  42.         save_scan[0] = SAVED_RLE_ROW(img, y-1);
  43.         for (i=1; i < img->img_channels; i++)
  44.             read_scan[i] = read_scan[i-1] + img->w,
  45.             save_scan[i] = save_scan[i-1] + img->w;
  46.         Map_Scanline(img, read_scan, save_scan, y, img->w,
  47.             determine_icon_size(img, &img->icn_w, &img->icn_h));
  48.     }
  49.     i = strlen(img->filename) + sizeof(HELP_INFO) + 8;
  50.     if (pointer_buffer_size(img->title) < i)
  51.         img->title = (char *)realloc(img->title, i);
  52.     sprintf(img->title, "%s(%d) %s", img->filename, img->RGB, HELP_INFO);
  53.     XStoreName(img->dpy, img->window, img->title);
  54.     XPutImage(img->dpy, img->window, img->gc, img->image,
  55.         0, 0, 0, 0, img->w, img->h);
  56. }
  57.  
  58. /* returns how many lines it blitted */
  59. void
  60. handle_exposure(img, x, y, width, height, img_h, sub_win)
  61. register image_information    *img;
  62. int    (*sub_win)();
  63. {
  64.     /*
  65.     * If window has been resized (bigger), dont bother redrawing
  66.     * the area outside the image.
  67.     */
  68.     if (x < 0)
  69.         width -= x,    x = 0;
  70.  
  71. /*    if the image has not yet read itself in, dont blit any of it
  72.     instead clear out that top portion of the window (not needed oh well)
  73. */
  74.  
  75.     if (y < img->h - img_h && img->in_type == RLE)    {
  76.         XClearArea(img->dpy, img->window, x, y,
  77.             width, img->h - img_h - y, False);
  78.         height -= img->h - img_h - y;
  79.         y = img->h - img_h;
  80.     }
  81.  
  82.     if (height <= 0)    return;    /* hardly happen */
  83.  
  84.     if (y + height >= img->h)
  85.         height = img->h - y;
  86.  
  87.     /*    if bitmap, round beginning pixel to beginning of word    */
  88.  
  89.     if (img->binary_img) {
  90.         int offset = x % BitmapPad (img->dpy);
  91.         x -= offset;
  92.         width += offset;
  93.     }
  94.     if (x + width >= img->w)
  95.         width = img->w - x;
  96.  
  97.     if (width <= 0 || height <= 0)
  98.         return;
  99.  
  100.     if (!tuner_flag && img->refresh_pixmap)
  101.         XCopyArea(img->dpy, img->refresh_pixmap, img->window, img->gc,
  102.             x, y, width, height, x, y);
  103.     else
  104.         XPutImage(img->dpy, img->window, img->gc, img->image,
  105.             x, y, x, y, width, height);
  106.     if (img->sub_img) {
  107.     XRectangle    r;
  108.         r.x = x;    r.y = y;
  109.         r.width = width;
  110.         r.height = height;
  111.         XSetClipRectangles(img->dpy, img->gc, 0, 0, &r, 1, Unsorted);
  112.         sub_win(img, 0, 0);
  113.         XSetClipMask(img->dpy, img->gc, None);
  114.     }
  115.     else    img->tmp_offset = 0;
  116. }
  117.  
  118. Map_Scanline(img, data_buf, save_scan, y, w, icon_factor)
  119. image_information*    img;
  120. byte    *data_buf[], *save_scan[];
  121. {
  122. if (img->mono_img)    /*    map  data_buf to save_scan    */
  123.     map_rgb_to_bw(img, data_buf, save_scan[0], w);    /* 0 = img->w */
  124. else
  125.     map_rgb_to_rgb(img, data_buf, save_scan, w);
  126.  
  127.     /*    map save_scan (1 line, width `w') to img->image->data    */
  128. (*img->map_scanline)(img, save_scan, img->dpy_channels, w, 1, y, img->image);
  129.  
  130.     /* Subsample image to create icon */
  131. if (img->icn_image && (y%icon_factor == 0))
  132.     (*img->map_scanline)(img, save_scan, img->dpy_channels,
  133.          img->icn_w, icon_factor, y / icon_factor, img->icn_image);
  134. if (img->in_type==RLE)    y--;
  135. return    y;
  136. }
  137.  
  138. Maintain_Flush(cur_img, previous, imgp, image_y)
  139. image_information    *previous, **imgp;
  140. {
  141. XEvent event;
  142. image_information    *img = imgp[cur_img];
  143.  
  144.     while (XPending(img->dpy)) {
  145.     XNextEvent(img->dpy, &event);
  146.     if (event.type == Expose) {
  147.         image_information *eimg;
  148.         register int     i;
  149.         /* get the right window bro....  */
  150.         i = WhichImage(event.xany.window, imgp, cur_img);
  151.         if (previous || i<0)
  152.             eimg = imgp[cur_img];    /*flip_book override */
  153.         else    eimg = imgp[i];
  154.         handle_exposure(eimg, event.xexpose.x, event.xexpose.y,
  155.             event.xexpose.width, event.xexpose.height, (i==cur_img) ?
  156.             (img->in_type==RLE) ? image_y : img->h-image_y : eimg->h,
  157.             DrawCrop);
  158.         XFlush(img->dpy);
  159.     }
  160.     }
  161. }
  162.  
  163. MapRGB(cur_img, previous, imgp, data_buf, save_scan, y, w, image_y, icon_factor)
  164. image_information    *previous, **imgp;
  165. byte    *data_buf[], *save_scan[];
  166. {
  167. y = Map_Scanline(imgp[cur_img], data_buf, save_scan, y, w, icon_factor);
  168. Maintain_Flush(cur_img, previous, imgp, image_y);
  169. return    y;
  170. }
  171.  
  172. void
  173. init_img_info(i, dpy)
  174. image_information *i;
  175. Display    *dpy;
  176. {
  177.     if (dpy)    i->dpy = dpy;
  178.     i->lvls = specified_levels;
  179.     i->window = i->icn_window = NULL;
  180.     i->pixmap = i->icn_pixmap = NULL;
  181.     i->pix_info_window = NULL;
  182.     i->gc = i->icn_gc = NULL;
  183.     i->image = i->icn_image = NULL;
  184.     i->colormap = NULL;
  185.     i->marray = zalloc(sizeof(*(i->marray)), 3, "m_3channel");
  186.     i->pixmap_failed = False;
  187.  
  188.     i->img_num = i->sub_img = multi_hd = 0;
  189.     i->filename = i->title = NULL;
  190.     i->fd = stdin;
  191.     i->OUT_FP = stdout;
  192.     i->img_channels = i->dpy_channels = 0;
  193.     i->scan_data = NULL;
  194.     i->map_scanline = NULL;
  195.     i->MAG_scanline = NULL;
  196.     i->gamma = 0.0;
  197.     format_init(i, IMAGE_INIT_TYPE, RLE, RLE, progname, VERS_COLOR_TUNER);
  198.     i->x = i->y = 0;
  199.     i->w = i->h = 0;
  200.     i->icn_w = i->icn_h = 0;
  201.  
  202.     i->mag_x = i->mag_x = 0;
  203.     i->mag_w = i->mag_h = 0;
  204.     i->mag_fact = 1;
  205.     i->save_mag_fact = 2;
  206.     i->mag_mode = False;
  207.     i->mag_pixmap = NULL;
  208.  
  209.     i->binary_img = False;
  210.     i->dither_img = False;
  211.     i->mono_img = False;
  212.     i->rw_cmap = False;
  213.     i->sep_colors = False;
  214.     i->mono_color = False;
  215.     i->color_dpy = True;
  216.  
  217.     i->in_cmap = NULL;
  218.     i->ncmap = i->cmlen = 0;
  219.     i->modN = NULL;
  220.     i->divN = NULL;
  221.     i->dm16 = NULL;
  222.     i->pixel_table = NULL;
  223.     if (!i->visual_class)
  224.         i->visual_class = -1;
  225. }
  226.  
  227. BuildColorImage(img, previous_img, window_geometry, icon_factor)
  228. image_information    *img, *previous_img;
  229. char    *window_geometry;
  230. int    *icon_factor;
  231. {
  232. extern void    choose_scanline_converter(), get_dither_colors();
  233. extern XImage    *get_X_image();
  234. extern int    eq_cmap();
  235.  
  236.     if (!img->title)    {
  237.         img->title = (char *) malloc(strlen(img->filename) +
  238.             sizeof(HELP_INFO) + 8);
  239.         sprintf(img->title, "%s(%d) %s", img->filename,
  240.         (img->in_type<RLE ? img->RGB : img->img_num) + 1, HELP_INFO);
  241.     }
  242.     if (!previous_img)    /* better after img->????_color set up. */
  243.         find_appropriate_visual(img);
  244.  
  245.     get_dither_colors(img);
  246.  
  247.     if (!previous_img)    /* Get X color map */
  248.         init_color(img);
  249.  
  250.     /*
  251.      * Here if we are flip_booking we gotta get nasty here... img->w, img->h
  252.      * and img->img_channels must match for well surely be screwed if they
  253.      * dont match up  and we flip_book
  254.      */
  255.     if (previous_img) {
  256.         if (img->w != previous_img->w || img->h != previous_img->h ||
  257.         img->img_channels != previous_img->img_channels){
  258.         prgmerr(0, "%s: Images %s & %s dont match in size or channels",
  259.             progname, previous_img->title, img->title);
  260.         return    (FATAL_FAILURE);
  261.         }
  262.         if ((img->mono_color &&
  263.         !eq_cmap(previous_img->in_cmap, previous_img->cmlen,
  264.             img->in_cmap, img->cmlen)))    {
  265.         prgmerr(0, "%s: Images %s and %s have different colormaps",
  266.             progname, previous_img->title, img->title);
  267.         return    (FATAL_FAILURE);
  268.         }
  269.     }
  270.  
  271.     /*
  272.      * Here we have to conserve memory on the client side and not allocate a
  273.      * new Ximage structure with associated memory for image data.  Also, if
  274.      * the server was unable to supply us with a pixmap in previous_img, then
  275.      * we need to save the XImage there...
  276.      */
  277.     if (!previous_img || previous_img->pixmap == NULL)    {
  278.         if (!img->image)
  279.         img->image = get_X_image(img, img->w+1, img->h, True);
  280.  
  281.         if (img->image == NULL) {
  282.         prgmerr(0, "problem getting XImage");
  283.         return    (MALLOC_FAILURE);
  284.         }
  285.     }
  286.     else    img->image = previous_img->image;
  287.  
  288.     /* only dick with the icon if we are not flip_booking */
  289.     if (!previous_img) {
  290.         *icon_factor = determine_icon_size(img,
  291.             &img->icn_w, &img->icn_h);
  292.  
  293.         if (!img->icn_image)
  294.             img->icn_image = get_X_image(img, img->icn_w, img->icn_h, 1);
  295.  
  296.         if (img->icn_image == NULL) {
  297.             prgmerr(0, "malloc for fancy icon");
  298.             return    (MALLOC_FAILURE);
  299.         }
  300.     }
  301.     /*
  302.     * Get image and icon windows of the right size
  303.     */
  304.     create_windows(img, window_geometry);
  305.     set_watch_cursor(img->window);
  306.     if (!img->map_scanline)
  307.         choose_scanline_converter(img);    /* map_scan L77 */
  308.     return    SUCCESS;
  309. }
  310.  
  311.  
  312. /*
  313. %    Read an image from the input file and display it.
  314. %    number of scan lines to be drawn in incremental mode
  315. */
  316.  
  317. #define LINES_DRAWN    10
  318.  
  319. get_pic(cur_img, window_geometry, previous_img, img_info)
  320. image_information    *previous_img, **img_info;
  321. char *window_geometry;
  322. {
  323. int    image_xmax, image_ymax, icon_factor;
  324. byte    *save_scan[3], *read_scan[3];
  325. register int    i, image_y, next_y, y_base, lines_buffered;
  326. register image_information    *img = img_info[cur_img];
  327.  
  328.     /*
  329.     * Read setup info from file.
  330.     */
  331.  
  332.     if ((i=(*img->header_handle)(HEADER_READ, img, 0, multi_hd, OsameI)) < 0)
  333.     return    i;    /* rle_err    */
  334.  
  335.     if (img->in_type == RLE)
  336.     image_xmax = rle_dflt_hdr.xmax,
  337.     image_ymax = rle_dflt_hdr.ymax;
  338.     else
  339.     image_xmax = img->w-1,
  340.     image_ymax = img->h-1;
  341.  
  342.     rle_dflt_hdr.xmin = 0;
  343.     rle_dflt_hdr.xmax = img->w - 1;
  344.  
  345.     if (img->img_channels < img->dpy_channels)
  346.     message("%s (get_pic): dpy_channels %d > img_channels %d\n", progname,
  347.          img->dpy_channels, img->img_channels);
  348.  
  349.     if (!img->title &&
  350.     !(img->title = rle_getcom("image_title", &rle_dflt_hdr )) &&
  351.     !(img->title = rle_getcom("IMAGE_TITLE", &rle_dflt_hdr )) &&
  352.     !(img->title = rle_getcom("title", &rle_dflt_hdr)) &&
  353.     !(img->title = rle_getcom("TITLE", &rle_dflt_hdr)) )    {}
  354.  
  355.     i = BuildColorImage(img, previous_img, window_geometry, &icon_factor);
  356.     if (i != SUCCESS)
  357.     return    i;
  358.  
  359.     /*
  360.     * If we are going to display a 2 or 3 channel image in one channel (-w)
  361.     * we have to copy the data anyway, so we will always read it into the
  362.     * same spot, and map it into a saved_data array with only one color per
  363.     * scanline this saves memory.
  364.     *
  365.     * read_scan[] is the scan data that we read into with rle_getrow.
  366.     * If the number of image channels is equal to that which is displayed,
  367.     * we will not mallocate new memory for it, but we will move it
  368.     * throughout the saved_data along with save_scan.
  369.     *
  370.     * save_scan[] is the pointer to the current line in img->saved_data
  371.     * that we are saving rle_getrows into.
  372.     *
  373.     * If we cant malloc the memory for the save_scan[] or we are doing
  374.     * flip_book, then we dont want to malloc the memory for this thing.
  375.     *
  376.     * Set up for rle_getrow.  Pretend image x origin is 0.
  377.     */
  378.  
  379. /* get img->h rows mem. SAVED_RLE_ROW uses scan_data to calc address! */
  380.     read_scan[0] = img->scan_data = NULL;
  381.  
  382.     /* if we are flip_booking don't mess with this one huh ? */
  383.     if (!previous_img || tuner_flag) {    /* BIG bug in getx11 */
  384.     img->scan_data = (byte *) malloc(SAVED_RLE_ROW(img, img->h));
  385.  
  386.     if (! img->scan_data)
  387.         prgmerr(tuner_flag, "malloc for %s scanline buffer failed",
  388.             img->filename);
  389.  
  390.     /* use the macro to point us to the last line... start saving here */
  391.     save_scan[0] = SAVED_RLE_ROW(img, img->h - 1);
  392.     for (i=1; i < img->img_channels; i++)
  393.         save_scan[i] = save_scan[i-1] + img->w;
  394.     }
  395.  
  396.     /* get one line of scan data for reading if we are doing monochrome */
  397.  
  398.     if (img->mono_img && img->in_type==RLE ||
  399.         img->scan_data==NULL || tuner_flag) {
  400.     if (tuner_flag)
  401.         img->data = nzalloc(img->w * (img->h+1), img->img_channels);
  402.     else    if ((read_scan[0]=(byte*)malloc(img->w*img->img_channels))==NULL){
  403.         prgmerr(0, "malloc for read_scan buffer failed");
  404.         return    (MALLOC_FAILURE);
  405.     }
  406.  
  407.     if (read_scan[0]==0)
  408.         read_scan[0] = ORIG_RLE_ROW(img, img->h - 1);
  409.     for (i=1; i < img->img_channels; i++)
  410.         read_scan[i] = read_scan[i-1] + img->w;
  411.     if (img->scan_data == NULL)
  412.         save_scan[0] = read_scan[0],
  413.         save_scan[1] = read_scan[1],
  414.         save_scan[2] = read_scan[2];
  415.     }
  416.     else    read_scan[0] = save_scan[0],
  417.         read_scan[1] = save_scan[1],
  418.         read_scan[2] = save_scan[2];
  419.  
  420.     if (!img->data)
  421.     img->data = img->scan_data;
  422.  
  423.     if (img->in_type != RLE){ /* multiple-frame is applied to HIPS and FITS */
  424.     (*img->friend)(FI_LOAD_FILE, img, 0,
  425.         img->in_type==HIPS || img->in_type==FITS ? img->RGB : OsameI);
  426.     if (img->mono_img && !tuner_flag && img->in_type != RLE &&
  427.         img->scan_data==0)
  428.         img->scan_data = read_scan[0] = save_scan[0] = img->data;
  429.     }
  430. /*    For each scan line, read it, save it, dither it and display it    */
  431.     next_y = img->h - 1;
  432.  
  433.     for (lines_buffered=image_y=0; image_y<img->h; image_y++) {
  434.     int    y;
  435.     if (img->in_type == RLE)
  436.         y = rle_getrow(&rle_dflt_hdr, read_scan);
  437.     else    y = image_ymax - image_y;
  438.  
  439.     next_y = MapRGB(cur_img, previous_img, img_info, read_scan, save_scan,
  440.         image_ymax - y, img->w, y, icon_factor);
  441.  
  442.     if (++lines_buffered >= LINES_DRAWN || (img->fd==stdin && !jump_flag)){
  443.         y_base = next_y + 1 - (img->in_type==RLE ? 0 : lines_buffered);
  444.         XPutImage(img->dpy, img->pixmap?img->pixmap:img->window, img->gc,
  445.             img->image, 0, y_base, 0, y_base, img->w,lines_buffered);
  446.         if (img->pixmap)
  447.             XCopyArea(img->dpy, img->pixmap, img->window, img->gc, 0, y_base,
  448.               img->w, lines_buffered, 0, y_base);
  449.         lines_buffered = 0;
  450.     }
  451.  
  452.     if (img->scan_data) {
  453.         /* move scan up one line */
  454.         save_scan[0] = SAVED_RLE_ROW(img, next_y);
  455.         for (i=1; i < img->img_channels; i++)
  456.             save_scan[i] = save_scan[i-1] + img->w;
  457.     /*
  458.     * remember? if were saving more than one channel then we dont need
  459.     * to move the data after we read it...  So kludge read_scan ...
  460.     */
  461.         if (tuner_flag) {
  462.             read_scan[0] = ORIG_RLE_ROW(img, next_y);
  463.             for (i=1; i<img->img_channels; i++)
  464.             read_scan[i] = read_scan[i-1] + img->w;
  465.         } else    if (!img->mono_img || img->in_type != RLE)
  466.             read_scan[0] = save_scan[0],
  467.             read_scan[1] = save_scan[1],
  468.             read_scan[2] = save_scan[2];
  469.     } else    save_scan[0] = read_scan[0],
  470.         save_scan[1] = read_scan[1],
  471.         save_scan[2] = read_scan[2];
  472.     }
  473.     if (lines_buffered > 0) {
  474.     y_base = next_y + 1 - (img->in_type==RLE ? 0 : lines_buffered);
  475.     XPutImage(img->dpy, img->pixmap?img->pixmap:img->window, img->gc,
  476.         img->image, 0, y_base, 0, y_base, img->w, lines_buffered);
  477.     if (img->pixmap)
  478.         XCopyArea(img->dpy, img->pixmap, img->window, img->gc, 0, y_base,
  479.             img->w, lines_buffered, 0, y_base);
  480.     }
  481.  
  482.     if (!previous_img && img->icn_pixmap) {
  483.     XPutImage(img->dpy, img->icn_pixmap, img->icn_gc, img->icn_image,
  484.           0, 0, 0, 0, img->icn_w, img->icn_h);
  485.     XClearWindow(img->dpy, img->icn_window);
  486.     }
  487.  
  488.     set_circle_cursor(img->window);
  489.     if (tuner_flag)
  490.     img->hist = nzalloc(HistoSize*3, sizeof(*(img->hist)), "hist");
  491.  
  492. return (SUCCESS);
  493. }
  494.